#ifndef INSTRUCTIONFACTORY
#define INSTRUCTIONFACTORY

#include <vector>
#include <string>

class Instruction;
class Expression;

/**
	@class InstructionFactory
	@brief fabrique d'instruction

	classe statique permettant à l'analyseur de créer des instructions sans avoir besoin de connaitre la hiérarchisation des classes
*/
class InstructionFactory
{
	public:
		/**
			@brief creation d'un if simple

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : if ( condition ) instruction
			@param [in] condition l'instance représentant l'expression condition du if
			@param [in] codeAlors l'instance représentant l'instruction à exécuter si l'expression est évaluée à vrai
			@return une instance d'instruction représentant le if
		*/
		static Instruction* generateIfThen ( Expression* condition, Instruction* codeAlors );
		/**
			@brief creation d'un if avec clause else

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : if ( condition ) instruction else instruction
			@param [in] condition l'instance représentant l'expression condition du if
			@param [in] codeAlors l'instance représentant l'instruction à exécuter si l'expression est évaluée à vrai
			@param [in] codeSinon l'instance représentant l'instruction à exécuter si l'expression est évaluée à faux
			@return une instance d'instruction représentant le if else
		*/
		static Instruction* generateIfThenElse ( Expression* condition, Instruction* codeAlors, Instruction* codeSinon );
		/**
			@brief creation d'un for

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : for ( initialisation ; condition ; increment ) instruction
			@param [in] initialisation l'instance représentant l'instruction à exécuter pour initialiser le for
			@param [in] condition l'instance représentant l'expression condition pour rester dans le for
			@param [in] increment l'instance représentant l'instruction à exécuter en fin de for
			@param [in] codeBoucle l'instance représentant l'instruction à exécuter dans le for
			@return une instance d'instruction représentant le for
		*/
		static Instruction* generateFor ( Instruction* initialisation, Expression* condition, Instruction* increment, Instruction* codeBoucle );
		/**
			@brief creation d'un while

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : while ( condition ) instruction
			@param [in] condition l'instance représentant l'expression condition pour rester dans la boucle
			@param [in] codeBoucle l'instance représentant l'instruction à exécuter dans le while
			@return une instance d'instruction représentant le while
		*/
		static Instruction* generateWhile ( Expression* condition, Instruction* codeBoucle );
		/**
			@brief creation d'un repeat

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : do instruction while ( condition )
			@param [in] condition l'instance représentant l'expression condition pour sortir de la boucle
			@param [in] codeBoucle l'instance représentant l'instruction à exécuter dans le repeat
			@return une instance d'instruction représentant le repeat
		*/
		static Instruction* generateRepeat ( Expression* condition, Instruction* codeBoucle );
		/**
			@brief creation d'une affectation

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : expression = expression
			@param [in] aGauche l'instance représentant l'expression dans laquelle est stocké le résultat
			@param [in] aDroite l'instance représentant l'instruction à exécuter si l'expression est évaluée à vrai
			@return une instance d'instruction représentant l'affectation
		*/
		static Instruction* generateAffectation ( Expression* aGauche, Expression* aDroite );
		/**
			@brief creation d'un bloc de code

			Cette fonction va créer une instance de la classe ad-hoc pour gérer des instructions de type : { instructions }
			@param [in] listeInstruction l'instance de liste contenant la représentation interne des instructions à exécuter dans le bloc
			@return une instance d'instruction représentant le bloc de code
		*/
		static Instruction* generateBloc ( std::vector < Instruction* > listeInstruction );
		/**
			@brief creation d'un affichage

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : write ( expressions )
			@param [in] listeExpression l'instance de liste contenant la représentation interne des expressions à afficher
			@return une instance d'instruction représentant le write
		*/
		static Instruction* generateOutput ( std::vector < Expression* > listeExpression );
		/**
			@brief creation d'une lecture

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : read ( expressions )
			@param [in] listeExpression l'instance de liste contenant la représentation interne des expressions à lire
			@return une instance d'instruction représentant le read
		*/
		static Instruction* generateInput ( std::vector < Expression* > listeExpression );
		/**
			@brief creation d'un appel de procédure

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : f ( expressions )
			@param [in] name le nom de la procédure à appeler
			@param [in] listeExpression l'instance de liste contenant la représentation interne des expressions à passer en argument
			@return une instance d'instruction représentant l'appel de procédure
		*/
		static Instruction* generateCall ( const std::string& name, std::vector < Expression* > listeExpression );
		/**
		*/
		static Instruction* generateReturn ( Expression* aDroite );
};

#endif
